// Regular Expressions (正则表达式) 示例
// 演示 Pascal 中正则表达式的各种用法
program p_47_regular_expressions;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils,      // 系统工具单元
  RegExpr;       // 正则表达式单元

// 基本正则表达式匹配示例
procedure BasicRegularExpressionMatching;
var
  regex: TRegExpr;
  text: String;
begin
  WriteLn('1. 基本正则表达式匹配:');
  text := 'Hello, my email is user@example.com and phone is 123-456-7890';
  
  WriteLn('  测试文本: "', text, '"');
  
  regex := TRegExpr.Create;
  try
    // 匹配邮箱地址
    regex.Expression := '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}';
    if regex.Exec(text) then
    begin
      WriteLn('  邮箱匹配成功: "', regex.Match[0], '"');
      WriteLn('  匹配位置: ', regex.MatchPos[0], ' - ', regex.MatchPos[0] + regex.MatchLen[0] - 1);
    end
    else
      WriteLn('  未找到邮箱地址');
    
    // 匹配电话号码
    regex.Expression := '\d{3}-\d{3}-\d{4}';
    if regex.Exec(text) then
      WriteLn('  电话匹配成功: "', regex.Match[0], '"')
    else
      WriteLn('  未找到电话号码');
    
    // 匹配单词
    regex.Expression := '\b\w{5}\b';  // 5个字母的单词
    WriteLn('  5个字母的单词:');
    var found := regex.Exec(text);
    while found do
    begin
      WriteLn('    "', regex.Match[0], '" 在位置 ', regex.MatchPos[0]);
      found := regex.ExecNext;
    end;
  finally
    regex.Free;
  end;
end;

// 字符类和量词使用示例
procedure CharacterClassesAndQuantifiers;
var
  regex: TRegExpr;
  text: String;
begin
  WriteLn('2. 字符类和量词使用:');
  
  regex := TRegExpr.Create;
  try
    // 使用字符类
    text := 'Price: $29.99, Discount: 15%, Code: ABC123';
    WriteLn('  测试文本: "', text, '"');
    
    regex.Expression := '\d+';  // 匹配一个或多个数字
    WriteLn('  匹配数字:');
    var found := regex.Exec(text);
    while found do
    begin
      WriteLn('    "', regex.Match[0], '"');
      found := regex.ExecNext;
    end;
    
    regex.Expression := '[A-Z]+';  // 匹配一个或多个大写字母
    WriteLn('  匹配大写字母:');
    found := regex.Exec(text);
    while found do
    begin
      WriteLn('    "', regex.Match[0], '"');
      found := regex.ExecNext;
    end;
    
    // 使用量词
    text := 'aaaa bbb cc d eeee fff';
    WriteLn('  测试文本: "', text, '"');
    
    regex.Expression := '\w{3,}';  // 匹配3个或更多字符的单词
    WriteLn('  3个或更多字符的单词:');
    found := regex.Exec(text);
    while found do
    begin
      WriteLn('    "', regex.Match[0], '"');
      found := regex.ExecNext;
    end;
    
    regex.Expression := '\w{2,4}';  // 匹配2到4个字符的单词
    WriteLn('  2到4个字符的单词:');
    found := regex.Exec(text);
    while found do
    begin
      WriteLn('    "', regex.Match[0], '"');
      found := regex.ExecNext;
    end;
  finally
    regex.Free;
  end;
end;

// 分组和捕获功能示例
procedure GroupingAndCapturing;
var
  regex: TRegExpr;
  text: String;
begin
  WriteLn('3. 分组和捕获功能:');
  
  regex := TRegExpr.Create;
  try
    // 使用分组提取信息
    text := 'John Doe, 25 years old, email: john@example.com';
    WriteLn('  测试文本: "', text, '"');
    
    regex.Expression := '(\w+)\s+(\w+),\s+(\d+)\s+years\s+old';
    if regex.Exec(text) then
    begin
      WriteLn('  姓名: ', regex.Match[1], ' ', regex.Match[2]);
      WriteLn('  年龄: ', regex.Match[3]);
    end;
    
    // 提取邮箱信息
    text := 'Contact: john@example.com or jane@test.org';
    WriteLn('  测试文本: "', text, '"');
    
    regex.Expression := '(\w+)@([\w.-]+\.\w+)';
    WriteLn('  邮箱信息:');
    var found := regex.Exec(text);
    while found do
    begin
      WriteLn('    用户名: ', regex.Match[1]);
      WriteLn('    域名: ', regex.Match[2]);
      found := regex.ExecNext;
    end;
  finally
    regex.Free;
  end;
end;

// 文本替换和分割示例
procedure TextReplacementAndSplitting;
var
  regex: TRegExpr;
  text: String;
  resultText: String;
begin
  WriteLn('4. 文本替换和分割:');
  
  regex := TRegExpr.Create;
  try
    // 文本替换
    text := 'The quick brown fox jumps over the lazy dog. The fox is quick.';
    WriteLn('  原始文本: "', text, '"');
    
    regex.Expression := 'fox';
    resultText := regex.Replace(text, 'cat', True);
    WriteLn('  替换结果: "', resultText, '"');
    
    regex.Expression := 'the';
    resultText := regex.Replace(text, 'a', False);  // 不区分大小写
    WriteLn('  忽略大小写替换: "', resultText, '"');
    
    // 隐藏敏感信息
    text := 'Contact me at john@example.com or call 123-456-7890';
    WriteLn('  敏感信息文本: "', text, '"');
    
    regex.Expression := '\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b';
    resultText := regex.Replace(text, '[EMAIL]', True);
    WriteLn('  隐藏邮箱后: "', resultText, '"');
    
    regex.Expression := '\b\d{3}-\d{3}-\d{4}\b';
    resultText := regex.Replace(text, '[PHONE]', True);
    WriteLn('  隐藏电话后: "', resultText, '"');
    
    // 文本分割
    text := 'apple,banana;orange:grape|kiwi';
    WriteLn('  分割文本: "', text, '"');
    
    regex.Expression := '[,;:|]';
    var parts := regex.Split(text);
    WriteLn('  分割结果:');
    for var i := 0 to High(parts) do
      WriteLn('    [', i, '] = "', parts[i], '"');
  finally
    regex.Free;
  end;
end;

// 常见模式匹配示例
procedure CommonPatternMatching;
var
  regex: TRegExpr;
begin
  WriteLn('5. 常见模式匹配:');
  
  regex := TRegExpr.Create;
  try
    // 邮箱验证
    regex.Expression := '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';
    var emails: array[0..3] of String = (
      'valid@example.com',
      'invalid.email',
      'test@domain.co.uk',
      '@invalid.com'
    );
    
    WriteLn('  邮箱验证:');
    for var i := 0 to 3 do
    begin
      if regex.Exec(emails[i]) then
        WriteLn('    "', emails[i], '" - 有效')
      else
        WriteLn('    "', emails[i], '" - 无效');
    end;
    
    // URL匹配
    regex.Expression := 'https?://[^\s/$.?#].[^\s]*';
    var urls: array[0..2] of String = (
      'http://www.example.com',
      'https://secure.example.org/path?param=value',
      'ftp://invalid.com'
    );
    
    WriteLn('  URL匹配:');
    for var i := 0 to 2 do
    begin
      if regex.Exec(urls[i]) then
        WriteLn('    "', urls[i], '" - 匹配')
      else
        WriteLn('    "', urls[i], '" - 不匹配');
    end;
    
    // IP地址匹配
    regex.Expression := '\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b';
    var ips: array[0..3] of String = (
      '192.168.1.1',
      '255.255.255.255',
      '999.999.999.999',
      '10.0.0.1'
    );
    
    WriteLn('  IP地址匹配:');
    for var i := 0 to 3 do
    begin
      if regex.Exec(ips[i]) then
        WriteLn('    "', ips[i], '" - 匹配')
      else
        WriteLn('    "', ips[i], '" - 不匹配');
    end;
  finally
    regex.Free;
  end;
end;

// 正则表达式在实际问题中的应用示例
procedure PracticalRegularExpressionApplications;
var
  regex: TRegExpr;
  logText: String;
begin
  WriteLn('6. 正则表达式在实际问题中的应用:');
  
  regex := TRegExpr.Create;
  try
    // 日志分析示例
    logText := '2025-09-25 14:30:45 INFO User login: john_doe' + LineEnding +
               '2025-09-25 14:31:12 ERROR Database connection failed' + LineEnding +
               '2025-09-25 14:32:01 WARN High memory usage detected' + LineEnding +
               '2025-09-25 14:32:45 INFO User logout: john_doe';
    
    WriteLn('  日志分析:');
    WriteLn('    日志内容:');
    var logLines := logText.Split([LineEnding]);
    for var i := 0 to High(logLines) do
      WriteLn('      ', logLines[i]);
    
    // 提取错误日志
    regex.Expression := '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (ERROR) (.*)';
    WriteLn('    错误日志:');
    var found := regex.Exec(logText);
    while found do
    begin
      WriteLn('      时间: ', regex.Match[1]);
      WriteLn('      级别: ', regex.Match[2]);
      WriteLn('      消息: ', regex.Match[3]);
      found := regex.ExecNext;
    end;
    
    // 数据清洗示例
    var dirtyData := 'Name: John Doe   Age: 30   Email: john@example.com   ';
    WriteLn('  数据清洗:');
    WriteLn('    原始数据: "', dirtyData, '"');
    
    // 清理多余空格
    regex.Expression := '\s+';
    var cleanData := regex.Replace(dirtyData, ' ', True);
    WriteLn('    清理空格后: "', Trim(cleanData), '"');
    
    // 提取结构化数据
    regex.Expression := 'Name:\s*(\w+\s+\w+)\s+Age:\s*(\d+)\s+Email:\s*([\w.@]+)';
    if regex.Exec(dirtyData) then
    begin
      WriteLn('    提取的数据:');
      WriteLn('      姓名: ', regex.Match[1]);
      WriteLn('      年龄: ', regex.Match[2]);
      WriteLn('      邮箱: ', regex.Match[3]);
    end;
  finally
    regex.Free;
  end;
end;

// 程序主入口
begin
  WriteLn('=== Pascal 正则表达式示例 ===');
  WriteLn;
  
  // 1. 基本正则表达式匹配
  BasicRegularExpressionMatching;
  
  WriteLn;
  
  // 2. 字符类和量词使用
  CharacterClassesAndQuantifiers;
  
  WriteLn;
  
  // 3. 分组和捕获功能
  GroupingAndCapturing;
  
  WriteLn;
  
  // 4. 文本替换和分割
  TextReplacementAndSplitting;
  
  WriteLn;
  
  // 5. 常见模式匹配
  CommonPatternMatching;
  
  WriteLn;
  
  // 6. 正则表达式在实际问题中的应用
  PracticalRegularExpressionApplications;
  
  WriteLn;
  WriteLn('演示了 Pascal 中正则表达式的各种用法');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.